<template>
	<view class="fixed zIndex-12 flex" :style="_pos?.parent">
		<!-- 主按钮。 -->
		<view :style="{width:props.width+'rpx',height:props.height+'rpx'}" class="flex flex-row flex-row-center-center">
			<slot>
				<tm-button :followTheme="props.followTheme" @click="onclick"
					_class="flex flex-col flex-col-center-center" :shadow="3" :linear="_btn.linear"
					:linear-deep="_btn.linearDeep" :color="_btn.color" :margin="[0, 0]" :round="16" :padding="[0, 0]"
					:width="props.width - 24" :height="props.height - 24">
					<view class="flex flex-col flex-col-center-center">
						<tm-icon :userInteractionEnabled="false" :follow-dark="false" :color="_btn.fontColor"
							:name="_btn.icon" :font-size="_btn.iconSize"></tm-icon>
						<tm-text :userInteractionEnabled="false" :follow-dark="false" :color="_btn.fontColor"
							v-if="_btn.label" :label="_btn.label" :font-size="_btn.fontSize"></tm-text>
					</view>
				</tm-button>
			</slot>
		</view>
		<!-- 子按钮。 -->
		<view v-if="showActions&& _actionsItem.length>0" class="fixed zIndex-12 flex " :style="_pos?.children"
			:userInteractionEnabled="showActions">
			
			<view ref="btnChildren" :style="{width:props.width+'rpx',height:props.height+'rpx'}" :class="[showActions&& _actionsItem.length>0?'scaleNvue':'']" class="flex flex-row flex-row-center-center scale" v-for="(item, index) in _actionsItem" :key="index">
				<tm-button :followTheme="props.followTheme" @click="change(index,item)"
					_class="flex flex-col flex-col-center-center" :shadow="3" :linear="item.linear"
					:linear-deep="item.linearDeep" :color="item.color" :margin="[0, 0]" :round="16" :padding="[0, 0]"
					:width="props.width - 24" :height="props.height - 24">
					<view class="flex flex-col flex-col-center-center">
						<tm-icon :userInteractionEnabled="false" :follow-dark="false" :color="item.fontColor"
							:name="item.icon" :font-size="item.iconSize"></tm-icon>
						<tm-text :userInteractionEnabled="false" :follow-dark="false" :color="item.fontColor"
							v-if="item.label" :label="item.label" :font-size="item.fontSize"></tm-text>
					</view>
				</tm-button>
			</view>

		</view>
	</view>
</template>
<script lang="ts" setup>
	/**
	 * 悬浮按钮
	 * @description 总共6个位置，每个位置有四方向的子按钮展开位置，一共24个位置可控制。具体看文档。
	 * @example <tm-floatButton :btn="{icon:'tmicon-plus',linear:'top'}"></tm-floatButton>
	 * @method click 主按钮被点击，(e:Event)
	 * @method change  子按钮被点击， (index:number,item:actionsItem)
	 */
	import { computed, PropType, ref, inject,getCurrentInstance, onMounted } from "vue";
	import { positionType, popDir, actionsItem } from "./interface";
	import tmSheet from "../tm-sheet/tm-sheet.vue";
	import tmIcon from "../tm-icon/tm-icon.vue";
	import tmText from "../tm-text/tm-text.vue";
	import tmButton from "../tm-button/tm-button.vue";
	// #ifdef APP-PLUS-NVUE
	const animation = uni.requireNativePlugin("animation");
	// #endif
	/**
	 * 事件说明
	 * click：主按钮被点击，
	 * change :子按钮被点击，
	 */
	const emits = defineEmits(["click", "change"]);
	const props = defineProps({
		followTheme: {
			type: [Boolean],
			default: true,
		},
		//主按钮的位置
		position: {
			type: String as PropType < "bc" | "bl" | "br" | "tc" | "tl" | "tr" > ,
			default: "br",
		},
		//子菜单弹出的位置
		actionsPos: {
			type: String as PropType < "left" | "right" | "top" | "bottom" > ,
			default: "top"
		},
		width: {
			type: Number,
			default: 124,
		},
		height: {
			type: Number,
			default: 124,
		},
		offset: {
			type: Array as PropType < Array < number >> ,
			default: () => [32,32],
		},
		//子按钮组数据
		actions: {
			type: Array as PropType < Array < actionsItem >> ,
			default: () => [],
		},
		// 主按钮对象数据
		btn: {
			type: Object as PropType < actionsItem > ,
			default: () => {},
			required: true,
		},
		//是否默认显示子菜单
		showActions: {
			type: Boolean,
			default: false,
		},
		//点击子菜单后，是否需要隐藏，如果为false,点击子按钮后不会隐藏按钮。始终保持展开子按钮。
		clickHidnActions: {
			type: Boolean,
			default: true,
		},
		disabledScrollTo: {
			type: Boolean,
			default: true,
		},
		scrollTo: {
			type: Object as PropType < { scrollTop: number;selector: string;duration: number } > ,
			default: () => {
				return {
					scrollTop: 0,
					selector: "",
					duration: 300,
				};
			},
		},
	});

	const sysinfo = inject(
		"tmuiSysInfo",
		computed(() => {
			return {
				bottom: 0,
				height: 750,
				width: uni.upx2px(750),
				top: 0,
				isCustomHeader: false,
				sysinfo: null,
			};
		})
	);
	const windowWidth = computed(() => sysinfo.value.width);
	const windowTop = computed(() => sysinfo.value.top);
	const proxy = getCurrentInstance()?.proxy??null;
	const isH5 = ref(false);
	// #ifdef H5
	isH5.value = true;
	// #endif
	const showActions = ref(props.showActions ?? false);
	const BtnPos = computed(() => props.position);
	const AcionPos = computed(() => props.actionsPos);
	const _offset = computed(() => {
		let ost = props.offset ?? [0, 0];
		ost = [uni.upx2px(props.offset[0]), uni.upx2px(props.offset[1])];
		return ost;
	});
	const centerPosLeft = computed(() => {
		let ps = (windowWidth.value - uni.upx2px(props.width * 2)) / 2 + _offset.value[0] * 2;
		return ps;
	});
	const btn_size = computed(() => uni.upx2px(props.width))
	const _btn = computed(() => {
		return {
			icon: "tmicon-plus",
			fontSize: 20,
			color: "primary",
			linear: "",
			linearDeep: "accent",
			label: "",
			iconSize: 42,
			fontColor: "",
			...(props.btn ?? {}),
		};
	});
	const _actionsItem = computed(() => {
		let asbtn = props.actions.map((el) => {
			let default_btn: actionsItem = {
				icon: "tmicon-plus",
				fontSize: 20,
				color: "primary",
				linear: "",
				linearDeep: "accent",
				label: "",
				fontColor: "",
				iconSize: 36,
			};
			return { ...default_btn, ...el };
		});
		return asbtn;
	});


	const _pos = computed(() => {
		let gutter = uni.upx2px(24)
		let actionwidth_total = _actionsItem.value.length*uni.upx2px(props.width)
		let actionwidth = uni.upx2px(props.width);
		if (AcionPos.value == "left" && BtnPos.value == "bc") {
			return {
				parent: {
					bottom: _offset.value[1] + 'px',
					left: centerPosLeft.value + 'px'
				},
				children: {
					bottom: _offset.value[1] + 'px',
					left: centerPosLeft.value-actionwidth_total + 'px',
					display:'flex',
					"flex-direction": "row",
				}
			}
		}
		if (AcionPos.value == "right" && BtnPos.value == "bc") {
			return {
				parent: {
					bottom: _offset.value[1] + 'px',
					left: centerPosLeft.value + 'px'
				},
				children: {
					bottom: _offset.value[1] + 'px',
					left: centerPosLeft.value+actionwidth + 'px',
					display:'flex',
					"flex-direction": "row",
				}
			}
		}
		if (AcionPos.value == "bottom" && BtnPos.value == "bc") {
			return {
				parent: {
					bottom: _offset.value[1] + 'px',
					left: centerPosLeft.value + 'px'
				},
				children: {
					bottom: (_offset.value[1] - actionwidth_total)+ 'px',
					left: centerPosLeft.value + 'px'
				}
			}
		}
		if (AcionPos.value == "top" && BtnPos.value == "bc") {
			return {
				parent: {
					bottom: _offset.value[1] + 'px',
					left: centerPosLeft.value + 'px'
				},
				children: {
					bottom: (_offset.value[1] + actionwidth) + 'px',
					left: centerPosLeft.value + 'px'
				}
			}
		}
		
		if (AcionPos.value == "right" && BtnPos.value == "bl") {
			return {
				parent: {
					bottom: _offset.value[1] + 'px',
					left: _offset.value[0] + 'px'
				},
				children: {
					bottom: _offset.value[1] + 'px',
					left: _offset.value[0]+actionwidth + 'px',
					display:'flex',
					"flex-direction": "row",
				}
			}
		}
		if (AcionPos.value == "left" && BtnPos.value == "bl") {
			return {
				parent: {
					bottom: _offset.value[1] + 'px',
					left: _offset.value[0] + 'px'
				},
				children: {
					bottom: _offset.value[1] + 'px',
					left: _offset.value[0]- actionwidth_total + 'px',
					display:'flex',
					"flex-direction": "row",
				}
			}
		}
		if (AcionPos.value == "top" && BtnPos.value == "bl") {
			return {
				parent: {
					bottom: _offset.value[1] + 'px',
					left: _offset.value[0] + 'px'
				},
				children: {
					bottom: (_offset.value[1] + actionwidth) + 'px',
					left: _offset.value[0] + 'px',
				}
			}
		}
		if (AcionPos.value == "bottom" && BtnPos.value == "bl") {
			return {
				parent: {
					bottom: _offset.value[1] + 'px',
					left: _offset.value[0] + 'px'
				},
				children: {
					bottom: (_offset.value[1] - actionwidth_total)+ 'px',
					left: _offset.value[0] + 'px',
				},
			}
		}
		
		if (AcionPos.value == "right" && BtnPos.value == "br") {
			return {
				parent: {
					bottom: _offset.value[1] + 'px',
					right: _offset.value[0] + 'px'
				},
				children: {
					bottom: _offset.value[1] + 'px',
					right: (_offset.value[0]-actionwidth_total) + 'px',
					display:'flex',
					"flex-direction": "row",
				}
			}
		}
		if (AcionPos.value == "left" && BtnPos.value == "br") {
			return {
				parent: {
					bottom: _offset.value[1] + 'px',
					right: _offset.value[0] + 'px'
				},
				children: {
					bottom: _offset.value[1] + 'px',
					right: _offset.value[0]+actionwidth + 'px',
					display:'flex',
					"flex-direction": "row",
				}
			}
		}
		if (AcionPos.value == "top" && BtnPos.value == "br") {
			return {
				parent: {
					bottom: _offset.value[1] + 'px',
					right: _offset.value[0] + 'px'
				},
				children: {
					bottom: (_offset.value[1] + actionwidth) + 'px',
					right: _offset.value[0] + 'px',
				}
			}
		}
		if (AcionPos.value == "bottom" && BtnPos.value == "br") {
			return {
				parent: {
					bottom: _offset.value[1] + 'px',
					right: _offset.value[0] + 'px'
				},
				children: {
					bottom: (_offset.value[1] - actionwidth_total)+ 'px',
					right: _offset.value[0] + 'px',
				},
			}
		}
		
		
		if (AcionPos.value == "left" && BtnPos.value == "tc") {
			return {
				parent: {
					top: _offset.value[1] + 'px',
					left: centerPosLeft.value + 'px'
				},
				children: {
					top: _offset.value[1] + 'px',
					left: centerPosLeft.value-actionwidth_total + 'px',
					display:'flex',
					"flex-direction": "row",
				}
			}
		}
		if (AcionPos.value == "right" && BtnPos.value == "tc") {
			return {
				parent: {
					top: _offset.value[1] + 'px',
					left: centerPosLeft.value + 'px'
				},
				children: {
					top: _offset.value[1] + 'px',
					left: centerPosLeft.value+actionwidth + 'px',
					display:'flex',
					"flex-direction": "row",
				}
			}
		}
		if (AcionPos.value == "bottom" && BtnPos.value == "tc") {
			return {
				parent: {
					top: _offset.value[1] + 'px',
					left: centerPosLeft.value + 'px'
				},
				children: {
					top: (_offset.value[1] + actionwidth) + 'px',
					left: centerPosLeft.value + 'px'
				}
			}
		}
		if (AcionPos.value == "top" && BtnPos.value == "tc") {
			return {
				parent: {
					top: _offset.value[1] + 'px',
					left: centerPosLeft.value + 'px'
				},
				children: {
					top: (_offset.value[1] - actionwidth_total)+ 'px',
					left: centerPosLeft.value + 'px'
				}
			}
		}
		
		if (AcionPos.value == "right" && BtnPos.value == "tl") {
			return {
				parent: {
					top: _offset.value[1] + 'px',
					left: _offset.value[0] + 'px'
				},
				children: {
					top: _offset.value[1] + 'px',
					left: _offset.value[0]+actionwidth + 'px',
					display:'flex',
					"flex-direction": "row",
				}
			}
		}
		if (AcionPos.value == "left" && BtnPos.value == "tl") {
			return {
				parent: {
					top: _offset.value[1] + 'px',
					left: _offset.value[0] + 'px'
				},
				children: {
					top: _offset.value[1] + 'px',
					left: _offset.value[0]- actionwidth_total + 'px',
					display:'flex',
					"flex-direction": "row",
				}
			}
		}
		if (AcionPos.value == "top" && BtnPos.value == "tl") {
			return {
				parent: {
					top: _offset.value[1] + 'px',
					left: _offset.value[0] + 'px'
				},
				children: {
					top: (_offset.value[1] - actionwidth_total)+ 'px',
					left: _offset.value[0] + 'px',
				}
			}
		}
		if (AcionPos.value == "bottom" && BtnPos.value == "tl") {
			return {
				parent: {
					top: _offset.value[1] + 'px',
					left: _offset.value[0] + 'px'
				},
				children: {
					top:(_offset.value[1] + actionwidth) + 'px', 
					left: _offset.value[0] + 'px',
				},
			}
		}
		
		if (AcionPos.value == "right" && BtnPos.value == "tr") {
			return {
				parent: {
					top: _offset.value[1] + 'px',
					right: _offset.value[0] + 'px'
				},
				children: {
					top: _offset.value[1] + 'px',
					right: (_offset.value[0]-actionwidth_total) + 'px',
					display:'flex',
					"flex-direction": "row",
				}
			}
		}
		if (AcionPos.value == "left" && BtnPos.value == "tr") {
			return {
				parent: {
					top: _offset.value[1] + 'px',
					right: _offset.value[0] + 'px'
				},
				children: {
					top: _offset.value[1] + 'px',
					right: _offset.value[0]+actionwidth + 'px',
					display:'flex',
					"flex-direction": "row",
				}
			}
		}
		if (AcionPos.value == "top" && BtnPos.value == "tr") {
			return {
				parent: {
					top: _offset.value[1] + 'px',
					right: _offset.value[0] + 'px'
				},
				children: {
					top: (_offset.value[1] - actionwidth_total)+ 'px',
					right: _offset.value[0] + 'px',
				}
			}
		}
		if (AcionPos.value == "bottom" && BtnPos.value == "tr") {
			return {
				parent: {
					top: _offset.value[1] + 'px',
					right: _offset.value[0] + 'px'
				},
				children: {
					top: (_offset.value[1] + actionwidth) + 'px',
					right: _offset.value[0] + 'px',
				},
			}
		}
		
		
	})

	function onclick(e: any) {
		if (props.clickHidnActions) {
			showActions.value = !showActions.value;
			// #ifdef APP-NVUE
			setTimeout(function() {
				nvueani()
			}, 50);
			// #endif
		} else {
			showActions.value = true;
		}
		emits("click", e);
		// #ifndef APP-NVUE
		if (!props.disabledScrollTo) {
			uni.pageScrollTo({
				scrollTop: props.scrollTo.scrollTop,
				duration: props.scrollTo.duration,
				selector: props.scrollTo.selector,
			});
		}
		// #endif
	}
	onMounted(()=>{
		if(showActions.value){
			// #ifdef APP-NVUE
			setTimeout(function() {
				nvueani()
			}, 50);
			// #endif
		}
	})
	function change(index: number, item: actionsItem) {
		if (props.clickHidnActions) {
			showActions.value = false;
		}
		emits("change", index, item);
	}
	function nvueani(){
		let el = proxy?.$refs?.btnChildren??null;
		if(!el) return;
		let pel = []
		if(!Array.isArray(el)){
			pel = [el]
		}else{
			pel = [...el]
		}
		pel.forEach(element=>{
			animation.transition(
			  element,
			  {
			    styles: {
					opacity: 1,
					transform: "scale(1,1)",
					transformOrigin: "center center",
				},
			    duration: 340, //ms
			    timingFunction: "ease",
			    delay: 0, //ms
			  },
			  () => {}
			);
		})
		
		
	}
</script>
<style scoped>
/* #ifdef APP-NVUE */
	.scaleNvue{
		opacity:0;
		transform: scale(0);
	}
/* #endif */
/* #ifndef APP-NVUE */
	.scale{
		animation: scale  0.34s ease;
	}
	@keyframes scale {
		0%{
			transform: scale(0);
		}

		40%{
			transform: scale(1.2);
		}
		100%{
			transform: scale(1);
		}
	}
/* #endif */
</style>
